package mobi.smarthosts;

import java.io.File;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Environment;
import android.preference.PreferenceManager;

public class Configuration {

    public static final String TAG = "SmartHosts";

    public static final String DATABASE_NAME = "smarthosts.db";
    public static final int DATABASE_VERSION = 1;

    public static final String CONTACT_SUPPORT = "tr.uecp@gmail.com";

    public static final String KEY_PACKAGE = "mobi.smarthosts.adfree.plugin";

    public static final String URL_MVPS_ADS_BLOCKING_HOSTS = "http://www.mvps.org/winhelp2002/hosts.txt";
    public static final String URL_SMART_HOSTS_ADFREE_HOSTS = "http://freehosts.sinaapp.com/android_adfree_hosts";

    public static final File HOSTS_SYSTEM   = new File("/system/etc/hosts");
    public static final File HOSTS_ORIGINAL = new File("/system/etc/hosts_orig");
    public static final File HOSTS_CLEAN    = new File("/system/etc/hosts_clean");
    public static final File HOSTS_BAK      = new File("/system/etc/hosts_bak");

    private static Configuration instance;
    protected Configuration() {}

    protected String mVersionName;
    public String getVersionName() { return mVersionName; }

    protected String mMainVersion;
    public String getMainVersion() { return mMainVersion; }

    protected String mBuildNum;
    public String getBuildNum() { return mBuildNum; }

    protected String mPackageName;
    public String getPackageName() { return mPackageName; }

    protected String mBuildDate;
    public String getBuildDate() { return mBuildDate; }

    protected File mHomeDir;
    public File getHomeDir() { return mHomeDir; }

    protected File mCacheDir;
    public File getCacheDir() { return mCacheDir; }

    protected File mTempDir;
    public File getTempDir() { return mTempDir; }

    private boolean mDebuggable;
    public boolean isDebuggable() { return mDebuggable; }

    private boolean mIsDonatedVersion;

    @SuppressWarnings("unchecked")
    public static <T extends Configuration> T init(Context context) {
        String packageName = null;
        try {
            packageName = context.getPackageName();
            instance = (Configuration) Class.forName(
                    packageName+"."+Configuration.class.getSimpleName()).newInstance();
                PackageInfo packageInfo = context.getPackageManager()
                        .getPackageInfo(packageName, PackageManager.GET_META_DATA);
                instance.mVersionName = packageInfo.versionName;
                instance.mBuildNum = context.getString(R.string.build_num);
                instance.mMainVersion = context.getString(R.string.build_version);
                instance.mBuildDate = context.getString(R.string.build_date);
                instance.mPackageName = packageName;

                instance.mHomeDir = Environment.getExternalStoragePublicDirectory(TAG);
                if (!instance.mHomeDir.exists()) {
                    instance.mHomeDir.mkdirs();
                }
                // to prevent scan by MediaScanner
                File nomediaIndecator = new File(instance.mHomeDir, ".nomedia");
                if (!nomediaIndecator.exists()) nomediaIndecator.createNewFile();

                instance.mCacheDir = new File(instance.mHomeDir, ".caches");
                if (!instance.mCacheDir.exists()) instance.mCacheDir.mkdirs();

                instance.mTempDir = new File(instance.mHomeDir, ".tmp");
                if (!instance.mTempDir.exists()) instance.mTempDir.mkdirs();
                else instance.clearTempFolder();

                instance.mDebuggable = (0 != (context.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE));

                try {
                    PackageInfo keyApps = context.getPackageManager()
                            .getPackageInfo(KEY_PACKAGE, PackageManager.GET_META_DATA);
                    instance.mIsDonatedVersion = (keyApps != null);
                } catch (NameNotFoundException e) {
                    instance.mIsDonatedVersion = false;
                }

        } catch (Exception e) {
            throw new SmartHostsException("Initial Configuration Failed.", e);
        }
        return (T) instance;
    }

    /**
     * This method should be call in Application or ContentProvider.
     */
    @SuppressWarnings("unchecked")
    public static <T extends Configuration> T getInstance(Context context) {
        if (instance == null) return init(context);
        return (T) instance;
    }

    /**
     * This method must be called after init().
     */
    @SuppressWarnings("unchecked")
    public static <T extends Configuration> T getInstance() {
        if (instance == null) throw new SmartHostsException("Configuration is not initialized.");
        return (T) instance;
    }


    public String getDatabaseName() {
        return DATABASE_NAME;
    }

    public int getDatabaseVersion() {
        return DATABASE_VERSION;
    }

    private String mAppName;
    public String getAppName(Context context) {
        if (mAppName == null) {
            mAppName = context.getString(R.string.app_name)
                +" "+getMainVersion()
                + (mIsDonatedVersion ? " Donated Version" : "");
        }
        return mAppName;
    }

    private String mUpdateSiteUrl;

    public String getServerUrl() {
        return mUpdateSiteUrl;
    }

    public String getUpdateSiteUrl(Context context) {
        // get update site URL, if not set, use default one and save.
        SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
        mUpdateSiteUrl = pref.getString(PrefKeys.KEY_UPDATE_SITE, null);
        if (Utils.isEmptyString(mUpdateSiteUrl)) {
            mUpdateSiteUrl = context.getResources().getStringArray(R.array.value_updateSites)[0];
            SharedPreferences.Editor editor = pref.edit();
            editor.putString(PrefKeys.KEY_UPDATE_SITE, mUpdateSiteUrl);
            editor.commit();
        }
        return mUpdateSiteUrl;
    }

    public void clearTempFolder() {
        Log.d("Recycle temporary folder.");
        Utils.deleteFolder(getTempDir());
    }

    public void clearCacheFolder() {
        Log.d("Recycle cache folder.");
        Utils.deleteFolder(getCacheDir());
    }

    public boolean isFirstTimeRunning(Context context) {
        SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
        String lastUpdateMD5 = pref.getString(PrefKeys.KEY_LAST_UPDATE_MD5, null);
        return lastUpdateMD5 == null;
    }

}
